package com.yanqu.road.logic.cross;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.RankListHelper;
import com.yanqu.road.logic.pb.CrossRankPb;
import com.yanqu.road.logic.sort.CrossRankSort;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.stream.IntStream;

public class CrossGroupRankListModel {

    private int bigRankType;

    private int rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;

    private CrossRankSort crossRankSort;

    private boolean isNeedSync = false;

    private LinkedList<CrossUserRank> rankList;

    private int rankType;

    private int groupId;

    public CrossGroupRankListModel(int groupId, int rankType, int bigRankType) {
        crossRankSort = new CrossRankSort();
        rankList = new LinkedList<>();
        this.groupId = groupId;
        this.rankType = rankType;
        this.bigRankType = bigRankType;
    }

    public int getBigRankType() {
        return bigRankType;
    }

    public int getGroupId() {
        return groupId;
    }

    public int getRankType() {
        return rankType;
    }

    public boolean isNeedSync() {
        return isNeedSync;
    }

    public void setNeedSync(boolean needSync) {
        isNeedSync = needSync;
    }

    public RankProto.RankListMsg.Builder getRankListMsg() {
        return initRankMsg();
    }

    public LinkedList<CrossUserRank> getRankList() {
        return rankList;
    }

    public void setRankList(LinkedList<CrossUserRank> userRankList) {
        synchronized (this) {
            rankList = new LinkedList<>(userRankList);
            if (bigRankType != eBigRankType.Patrons.getValue() || rankType != 0) {
                RankListHelper.checkUserRankListValid(rankList);       //校验一下数组
            }
            if (bigRankType != eBigRankType.Beauty.getValue() || rankType != 100) {
                RankListHelper.checkUserRankListValid(rankList);       //校验一下数组
            }
            rankList.sort(crossRankSort);
            while (rankList.size() > rankNum){
                rankList.removeLast();
            }
        }
    }

    private RankProto.RankListMsg.Builder initRankMsg() {
        return CrossRankPb.parseRankListMsg(new ArrayList<>(rankList));
    }

    public int getMyRank(long userId, long serverId) {
        synchronized (this) {
            OptionalInt result = IntStream.range(0, rankList.size()).filter(i -> rankList.get(i).getUserId() == userId &&
                    rankList.get(i).getUserBaseInfo().getServerId() == serverId).findFirst();
            if (result.isPresent()) {
                return result.getAsInt() + 1;
            }
            return -1;
        }
    }

    public CrossUserRank getMyRankInfo(long userId, long serverId) {
        synchronized (this) {
            OptionalInt result = IntStream.range(0, rankList.size()).filter(i -> rankList.get(i).getUserId() == userId &&
                    rankList.get(i).getUserBaseInfo().getServerId() == serverId).findFirst();
            if (result.isPresent()) {
                return rankList.get(result.getAsInt());
            }
            return null;
        }
    }

    public CrossUserRank getFirstRank(){
        if(rankList.size() > 0){
            return rankList.get(0);
        }
        return null;
    }

    /**
     * 添加到排行（最后更新时间）
     */
    public void rankChange2(CrossUserRank crossUserRank) {
        if(crossUserRank.getLastUpdateTime() == 0){
            return;
        }
        boolean isChange = false;
        synchronized (this) {
            int size = rankList.size();
            if (!rankList.stream().anyMatch(predicate -> predicate.getUserId() == crossUserRank.getUserId() &&
                    predicate.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId())) {
                if (size < rankNum) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(crossUserRank.getLastUpdateTime());
                    rankList.add(rank);
                    isChange = true;
                }else {
                    CrossUserRank lastValue = rankList.getLast();
                    if (crossRankSort.compare(crossUserRank, lastValue) < 0) {
                        replaceLastRank2(crossUserRank);
                        isChange = true;
                    }
                }
            } else {
                rankList.forEach(action -> {
                    if (action.getUserId() == crossUserRank.getUserId() && action.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId()) {
                        // 影响排行的值变化时，才更新时间
                        if (isRankDataChange(action, crossUserRank.getValue(), crossUserRank.getParam())) {
                            action.setLastUpdateTime(crossUserRank.getLastUpdateTime());
                        }
                        action.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                        action.setValue(crossUserRank.getValue());
                        action.setParam(crossUserRank.getParam());
                        action.setDelete(crossUserRank.isDelete());
                    }
                });
                isChange = true;
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                isNeedSync = true;
            }
        }
    }

    /**
     * 添加到排行
     */
    public void rankChange(CrossUserRank crossUserRank) {
        boolean isChange = false;
        synchronized (this) {
            int size = rankList.size();
            if (!rankList.stream().anyMatch(predicate -> predicate.getUserId() == crossUserRank.getUserId() &&
                    predicate.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId())) {
                if (size < rankNum) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.add(rank);
                    isChange = true;
                }else {
                    // 传到跨服的数据没有时间
                    if (crossUserRank.getLastUpdateTime() == 0) {
                        crossUserRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    }
                    CrossUserRank lastValue = rankList.getLast();
                    if (crossRankSort.compare(crossUserRank, lastValue) < 0) {
                        replaceLastRank(crossUserRank);
                        isChange = true;
                    }
                }
            } else {
                rankList.forEach(action -> {
                    if (action.getUserId() == crossUserRank.getUserId() && action.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId()) {
                        // 影响排行的值变化时，才更新时间
                        if (isRankDataChange(action, crossUserRank.getValue(), crossUserRank.getParam())) {
                            action.setLastUpdateTime(System.currentTimeMillis() / 1000);
                        }
                        action.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                        action.setValue(crossUserRank.getValue());
                        action.setParam(crossUserRank.getParam());
                        action.setDelete(crossUserRank.isDelete());
                    }
                });
                isChange = true;
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                isNeedSync = true;
            }
        }
    }

    /**
     * 添加到排行
     */
    public void allPatronsRankChange(CrossUserRank crossUserRank) {
        boolean isChange = false;
        synchronized (this) {
            int patronsId = JSONObject.parseObject(crossUserRank.getParam()).getIntValue("patronsId");
            int size = rankList.size();
            if (!rankList.stream().anyMatch(predicate -> predicate.getUserId() == crossUserRank.getUserId() &&
                    predicate.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId() &&
                    JSONObject.parseObject(predicate.getParam()).getIntValue("patronsId") == patronsId)) {
                if (size < rankNum) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.add(rank);
                    isChange = true;
                }else {
                    // 传到跨服的数据没有时间
                    if (crossUserRank.getLastUpdateTime() == 0) {
                        crossUserRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    }
                    CrossUserRank lastValue = rankList.getLast();
                    if (crossRankSort.compare(crossUserRank, lastValue) < 0) {
                        replaceLastRank(crossUserRank);
                        isChange = true;
                    }
                }
            } else {
                rankList.forEach(action -> {
                    if (action.getUserId() == crossUserRank.getUserId() && action.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId() && JSONObject.parseObject(action.getParam()).getIntValue("patronsId") == patronsId) {
                        // 影响排行的值变化时，才更新时间
                        if (isRankDataChange(action, crossUserRank.getValue(), crossUserRank.getParam())) {
                            action.setLastUpdateTime(System.currentTimeMillis() / 1000);
                        }
                        action.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                        action.setValue(crossUserRank.getValue());
                        action.setParam(crossUserRank.getParam());
                        action.setDelete(crossUserRank.isDelete());
                    }
                });
                isChange = true;
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                isNeedSync = true;
            }
        }
    }

    public void allBeautyRankChange(CrossUserRank crossUserRank) {
        boolean isChange = false;
        synchronized (this) {
            int beautyId = JSONObject.parseObject(crossUserRank.getParam()).getIntValue("id");
            int size = rankList.size();
            if (!rankList.stream().anyMatch(predicate -> predicate.getUserId() == crossUserRank.getUserId() &&
                    predicate.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId() &&
                    JSONObject.parseObject(predicate.getParam()).getIntValue("id") == beautyId)) {
                if (size < rankNum) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.add(rank);
                    isChange = true;
                }else {
                    // 传到跨服的数据没有时间
                    if (crossUserRank.getLastUpdateTime() == 0) {
                        crossUserRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    }
                    CrossUserRank lastValue = rankList.getLast();
                    if (crossRankSort.compare(crossUserRank, lastValue) < 0) {
                        replaceLastRank(crossUserRank);
                        isChange = true;
                    }
                }
            } else {
                rankList.forEach(action -> {
                    if (action.getUserId() == crossUserRank.getUserId() && action.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId() && JSONObject.parseObject(action.getParam()).getIntValue("id") == beautyId) {
                        // 影响排行的值变化时，才更新时间
                        if (isRankDataChange(action, crossUserRank.getValue(), crossUserRank.getParam())) {
                            action.setLastUpdateTime(System.currentTimeMillis() / 1000);
                        }
                        action.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                        action.setValue(crossUserRank.getValue());
                        action.setParam(crossUserRank.getParam());
                        action.setDelete(crossUserRank.isDelete());
                    }
                });
                isChange = true;
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                isNeedSync = true;
            }
        }
    }

    /**
     * 差异：最后更新时间
     */
    public void allRankChange2(CrossUserRank crossUserRank) {
        boolean isChange = false;
        synchronized (this) {
            int id = JSONObject.parseObject(crossUserRank.getParam()).getIntValue("id");
            int size = rankList.size();
            if (!rankList.stream().anyMatch(predicate -> predicate.getUserId() == crossUserRank.getUserId() &&
                    predicate.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId() &&
                    JSONObject.parseObject(predicate.getParam()).getIntValue("id") == id)) {
                if (size < rankNum) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(crossUserRank.getLastUpdateTime());
                    rankList.add(rank);
                    isChange = true;
                }else {
                    // 传到跨服的数据没有时间
                    if (crossUserRank.getLastUpdateTime() == 0) {
                        crossUserRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    }
                    CrossUserRank lastValue = rankList.getLast();
                    if (crossRankSort.compare(crossUserRank, lastValue) < 0) {
                        replaceLastRank2(crossUserRank);
                        isChange = true;
                    }
                }
            } else {
                rankList.forEach(action -> {
                    if (action.getUserId() == crossUserRank.getUserId() && action.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId() && JSONObject.parseObject(action.getParam()).getIntValue("id") == id) {
                        // 影响排行的值变化时，才更新时间
                        if (isRankDataChange(action, crossUserRank.getValue(), crossUserRank.getParam())) {
                            action.setLastUpdateTime(crossUserRank.getLastUpdateTime());
                        }
                        action.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                        action.setValue(crossUserRank.getValue());
                        action.setParam(crossUserRank.getParam());
                        action.setDelete(crossUserRank.isDelete());
                    }
                });
                isChange = true;
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                isNeedSync = true;
            }
        }
    }

    public BigInteger getMinRankScore() {
        synchronized (this) {
            if (rankList.size() > 0 && rankList.size() >= rankNum) {
                return rankList.getLast().getValue();
            }
            return BigInteger.ZERO;
        }
    }

    public void setRankNum(int rankNum) {
        this.rankNum = rankNum;
    }

    /**
     * 替换榜单最后一名
     */
    private CrossUserRank replaceLastRank(CrossUserRank crossUserRank) {
        CrossUserRank rank = rankList.getLast();
        rank.setUserId(crossUserRank.getUserId());
        rank.setUserBaseInfo(crossUserRank.getUserBaseInfo());
        rank.setValue(crossUserRank.getValue());
        rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
        rank.setParam(crossUserRank.getParam());
        rank.setDelete(crossUserRank.isDelete());
        return rank;
    }

    /**
     * 替换榜单最后一名
     */
    private CrossUserRank replaceLastRank2(CrossUserRank crossUserRank) {
        CrossUserRank rank = rankList.getLast();
        rank.setUserId(crossUserRank.getUserId());
        rank.setUserBaseInfo(crossUserRank.getUserBaseInfo());
        rank.setValue(crossUserRank.getValue());
        rank.setLastUpdateTime(crossUserRank.getLastUpdateTime());
        rank.setParam(crossUserRank.getParam());
        rank.setDelete(crossUserRank.isDelete());
        return rank;
    }

    /**
     * 排行数据是否变化
     */
    private boolean isRankDataChange(CrossUserRank oldRank, BigInteger value, String param) {
        CrossUserRank newRank = new CrossUserRank();
        newRank.setBigRankType(oldRank.getBigRankType());
        newRank.setType(oldRank.getType());
        newRank.setRank(oldRank.getRank());
        newRank.setUserId(oldRank.getUserId());
        newRank.setUserBaseInfo(oldRank.getUserBaseInfo());
        newRank.setLastUpdateTime(oldRank.getLastUpdateTime());
        // 影响排行榜的值
        newRank.setValue(value);
        newRank.setParam(param);
        return crossRankSort.compare(oldRank, newRank) != 0;
    }
}
